package com.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;

public class ImageBase64Util {
    static BASE64Encoder encoder = new BASE64Encoder();
    static BASE64Decoder decoder = new BASE64Decoder();

    private static Logger logger = LoggerFactory.getLogger(ImageBase64Util.class);


    public static void main(String[] args) {
        String filename = "/Users/jay/IdeaProjects/binguo/model/target/WechatIMG4000.jpeg";

        String ss = getImageBinary(filename);

        base64StringToImage(ss.toString(), filename + ".jpg");
    }

    public static String getImageBinary(String filename) {
        File f = new File(filename);
        try {
            BufferedImage bi = ImageIO.read(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, "jpg", baos);
            byte[] bytes = baos.toByteArray();

            return encoder.encodeBuffer(bytes).trim();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] getImageBytes(String filename) {
        File f = new File(filename);
        try {
            BufferedImage bi = ImageIO.read(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, "jpg", baos);
            byte[] bytes = baos.toByteArray();

            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String netImage(String srcImgPath, String filepath) {
        BufferedImage srcImage = null;
        try {
            srcImage = ImageIO.read(new URL(srcImgPath));

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            FileOutputStream fos = new FileOutputStream(filepath);
            ImageIO.write(srcImage, "jpg", fos);

            ImageIO.write(srcImage, "jpg", baos);
            byte[] bytes = baos.toByteArray();

            return encoder.encodeBuffer(bytes).trim();
        } catch (IOException e) {
            System.out.println("读取图片文件出错！" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public static boolean downloadNetImage(String srcImgPath, String filepath) {
        BufferedImage srcImage = null;
        try {
            srcImage = ImageIO.read(new URL(srcImgPath));

            FileOutputStream fos = new FileOutputStream(filepath);
            ImageIO.write(srcImage, "png", fos);

            return true;
        } catch (IOException e) {
            System.out.println("读取图片文件出错！" + e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

    public static byte[] netImageByte(String srcImgPath) {
        BufferedImage srcImage = null;
        try {
            srcImage = ImageIO.read(new URL(srcImgPath));


            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            ImageIO.write(srcImage, "jpg", baos);
            byte[] bytes = baos.toByteArray();

            return bytes;
        } catch (IOException e) {
            System.out.println("读取图片文件出错！" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public static Integer[] base64StringToImage(String base64String, String filepath) {
        try {
            byte[] bytes1 = decoder.decodeBuffer(base64String);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
            BufferedImage bi1 = ImageIO.read(bais);

            int width = bi1.getWidth();
            File f1 = new File(filepath);
            ImageIO.write(bi1, "png", f1);

            int height = bi1.getHeight();

            return new Integer[]{width, height};
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }
}
